﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Reflection;

namespace LibraryA.Utils
{
    /// <summary>
    /// The class is good if you want to load controls from the same library dynamically    
    /// It speed-up this operation because it works without reflection.
    /// </summary>
    public static class ControlsLoader
    {
        private static Dictionary<Assembly, Dictionary<Type, Type>> processedAssemblies = new Dictionary<Assembly, Dictionary<Type, Type>>();

        /// <summary>
        /// The function creates new instance of ASCX type associated with given codebehind type T
        /// </summary>
        /// <typeparam name="T">codebehind type</typeparam>
        /// <returns>newly created instance of ASCX type inherited from given codebehind type</returns>
        public static T LoadControl<T>() where T : UserControl, new()
        {
            Type type = typeof(T);

            if (!processedAssemblies.ContainsKey(type.Assembly))
                processedAssemblies[type.Assembly] = ProcessAssembly(type.Assembly);

            return (T)FastActivator.CreateInstance(processedAssemblies[type.Assembly][type]);
        }

        /// <summary>
        /// searches for ASCX/ASPX types within given assembly
        /// </summary>
        /// <param name="assembly"></param>
        /// <returns></returns>
        private static Dictionary<Type, Type> ProcessAssembly(Assembly assembly)
        {
            Dictionary<Type, Type> result = new Dictionary<Type, Type>();

            foreach (Type type in assembly.GetTypes())
            {
                if (type.Namespace == "ASP" && !type.BaseType.Namespace.StartsWith("System."))
                    result[type.BaseType] = type;                
            }

            return result;
        }
    }
}
